package com.ups.singlearner.util;

import com.ups.singlearner.ComposedNote;
import com.ups.singlearner.Composition;

import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.os.Handler;
import android.util.Log;

// originally from http://marblemice.blogspot.com/2010/04/generate-and-play-tone-in-android.html
// and modified by Steve Pomeroy <steve@staticfree.info>
// and modified again by Open Mind team !

public class PlaySoundUtil {
	private final static String TAG = "PlaySoundUtil";

	private final static int duration = 5; // seconds
	private final static int sampleRate = 8000;
	private final static int numSamples = duration * sampleRate;

	/*
	 * TODO, this start a new thread for each Note, not really a good idea...
	 * notes can be played in the wrong order !
	 */
	public static void playComposition(Composition c) {
		for (ComposedNote cn : c.getNotes()) {
			Log.d(TAG, "PLaying note : " + cn.getNote());
			playSoundFromFreq(NoteUtil.getFreqFromNote(cn.getNote()));
		}
	}

	public static void playSoundFromFreq(final float freq) {

		final byte[] generatedSound = new byte[2 * numSamples];
		generateTone(generatedSound, freq);

		playSoundFromByte(generatedSound);

	}

	private static void generateTone(byte[] generatedSound, float freq) {
		double sample[] = new double[numSamples];

		// fill the array
		for (int i = 0; i < numSamples; ++i) {
			sample[i] = Math.sin(2 * Math.PI * i / (sampleRate / freq));
		}

		// convert to 16 bit pcm sound array
		// assumes the sample buffer is normalised.
		int idx = 0;
		for (final double dVal : sample) {
			// scale to maximum amplitude
			final short val = (short) ((dVal * 32767));
			// in 16 bit wav PCM, first byte is the low order byte
			generatedSound[idx++] = (byte) (val & 0x00ff);
			generatedSound[idx++] = (byte) ((val & 0xff00) >>> 8);

		}
	}

	private static void playSoundFromByte(byte[] sound) {
		final AudioTrack audioTrack = new AudioTrack(
				AudioManager.STREAM_NOTIFICATION, sampleRate,
				AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT,
				numSamples, AudioTrack.MODE_STATIC);
		audioTrack.write(sound, 0, sound.length);
		audioTrack.play();
		audioTrack.release();
	}
}
